package org.zoomdev.zoom.timer.modules;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.aop.Invoker;
import org.zoomdev.zoom.aop.MethodInvokerFactory;
import org.zoomdev.zoom.common.utils.Classes;
import org.zoomdev.zoom.ioc.Ioc;
import org.zoomdev.zoom.ioc.IocKey;
import org.zoomdev.zoom.timer.TimerJob;
import org.zoomdev.zoom.timer.annotation.Timer;

import java.lang.reflect.Method;
import java.util.Collection;

final class InvokerTimerJob implements TimerJob {
    private final String comment;
    private final Method method;
    private final Invoker invoker;
    private final Ioc ioc;
    private final Class modelClass;
    private final Logger log = LoggerFactory.getLogger(CoreTimerModule.NAME);
    private Object target;
    private Object[] values;

    public InvokerTimerJob(Ioc ioc, Class modelClass, Method method) {
        Timer timer = method.getAnnotation(Timer.class);
        String comment = timer.comment();
        this.comment = StringUtils.isBlank(comment) ? Classes.getMethodDesc(method) : comment;
        this.method = method;
        this.invoker = MethodInvokerFactory.FACTORY.create(method);

        this.ioc = ioc;
        this.modelClass = modelClass;
    }

    @Override
    public String toString() {
        return comment;
    }

    @Override
    public void execute() throws Throwable {
        long now = System.currentTimeMillis();

        if (CoreTimerModule.enableLog) {
            log.info(String.format("定时任务[%s]执行开始", comment));
        }
        try {
            if (target == null) {
                Collection<IocKey> keys = ioc.find(modelClass);
                if (keys.isEmpty()) {
                    target = ioc.fetch(modelClass);
                } else {
                    //比较复杂
                    target = ioc.fetch(keys.iterator().next());
                }
                values = IocKey.getValues(ioc, IocKey.valuesFromMethod(method));
            }
            invoker.invoke(target, values);
        } finally {
            if (CoreTimerModule.enableLog) {
                log.info(String.format("定时任务[%s]执行完毕，耗时%s",
                        comment, getTimeDesc(System.currentTimeMillis() - now)));
            }
        }
    }


    private static String getTimeDesc(long ms) {
        if (ms < 1000) {
            return ms + "毫秒";
        }

        long sec = ms / 1000;
        if (sec < 60) {
            return sec + "秒";
        }

        long min = sec / 60;
        if (min < 60) {
            return min + "分" + (sec % 60) + "秒";
        }

        long hour = min / 60;
        return hour + "小时" + (min % 60) + "分" + (sec % 60) + "秒";
    }
}
